//===============================================================================
// Microsoft patterns & practices
// Web Client Software Factory
//-------------------------------------------------------------------------------
// Copyright (C) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE.
//-------------------------------------------------------------------------------
// The example companies, organizations, products, domain names,
// e-mail addresses, logos, people, places, and events depicted
// herein are fictitious.  No association with any real company,
// organization, product, domain name, email address, logo, person,
// places, or events is intended or should be inferred.
//===============================================================================
using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using WCSFContrib.PageFlow.Xml.Tests.Mocks;
using WCSFContrib.PageFlow;

namespace WCSFContrib.PageFlow.Xml.Tests
{
    [TestClass]
    public class XmlPageFlowInstanceFixture
    {
        internal readonly Guid TestGuid = new Guid("933E94C3-1B11-41cc-AEF2-E40175C90400");

        private MockXmlPageFlowRuntime runtime;

        [TestInitialize]
        public void Init()
        {
            runtime = new MockXmlPageFlowRuntime();
        }

        [TestMethod]
        public void CanCreateNew()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime );
            Assert.IsNotNull(instance);
        }

        [TestMethod]
        [ExpectedException(typeof(ArgumentException))]
        public void CreateNewFailsWithEmtpyId()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(Guid.Empty, typeof(MockUnconstrainedPageFlow), runtime);
        }

        [TestMethod]
        public void CreateNewFailsNullArguments()
        {
            try
            {
                XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, null, runtime);
            }
            catch (ArgumentNullException)
            {
                try
                {
                    XmlPageFlowInstance instance2 = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), null);
                }
                catch (ArgumentNullException)
                {
                    return;
                }
            }
            Assert.Fail("ArgumentNullException was not thrown");
        }

        [TestMethod]
        public void StartupPropertiesValues()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            Assert.AreEqual(TestGuid, instance.InstanceId);
            Assert.AreEqual(PageFlowStatus.NotStarted, instance.Status);
            Assert.AreEqual(typeof(MockUnconstrainedPageFlow), instance.PageFlowType);
            Assert.AreEqual(runtime, instance.Runtime);
        }

        [TestMethod]
        public void StartChangesStatus()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);

            instance.Start();
            Assert.AreEqual(PageFlowStatus.Running, instance.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void StartWhenStatusIsntNotStartedFails()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Start();
            Assert.IsTrue(instance.Status != PageFlowStatus.NotStarted);
            instance.Start();
        }

        [TestMethod]
        public void AbortCallsTerminateOnRuntime()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Start();
            Assert.IsFalse(runtime.TerminateCalled);
            instance.Abort();
            Assert.IsTrue(runtime.TerminateCalled);
            Assert.AreEqual(PageFlowStatus.Terminated, instance.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void AbortWhenStatusIsTerminatedFails()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Complete();
            Assert.AreEqual(PageFlowStatus.Terminated, instance.Status);
            instance.Abort();
        }

        [TestMethod]
        public void CompleteCallsTerminateOnRuntime()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Start();
            Assert.IsFalse(runtime.TerminateCalled);
            instance.Complete();
            Assert.IsTrue(runtime.TerminateCalled);
            Assert.AreEqual(PageFlowStatus.Terminated, instance.Status);
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void CompleteWhenStatusIsTerminatedFails()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Abort();
            Assert.AreEqual(PageFlowStatus.Terminated, instance.Status);
            instance.Complete();
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void SuspendWhenStatusIsntRunningFails()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            Assert.IsTrue(PageFlowStatus.Running != instance.Status);
            instance.Suspend();
        }

        [TestMethod]
        [ExpectedException(typeof(PageFlowException))]
        public void ResumeWhenStatusIsSuspendedFails()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Start();
            Assert.IsTrue(PageFlowStatus.Suspended != instance.Status);
            instance.Resume();
        }

        [TestMethod]
        public void PersistCallsPersistOnRuntime()
        {
            XmlPageFlowInstance instance = new XmlPageFlowInstance(TestGuid, typeof(MockUnconstrainedPageFlow), runtime);
            instance.Start();
            Assert.IsFalse(runtime.PersistCalled);
            instance.Persist();
            Assert.IsTrue(runtime.PersistCalled);
        }
    }


    class MockXmlPageFlowRuntime : XmlPageFlowRuntime
    {
        public bool PersistCalled;
        public bool TerminateCalled;

        public MockXmlPageFlowRuntime() : base(new InMemoryXmlPageFlowInstanceStore())
        {
        }

        #region IXmlPageFlowRuntime Members

        public override XmlPageFlowInstance CreatePageFlow(Type pageFlowType)
        {
            throw new NotImplementedException("The method or operation is not implemented.");
        }

        public override XmlPageFlowInstance GetPageFlow(Guid instanceId)
        {
            throw new NotImplementedException("The method or operation is not implemented.");
        }

        public override void Persist(XmlPageFlowInstance xmlPageFlowInstance)
        {
            PersistCalled = true;
        }

        public override void Terminate(XmlPageFlowInstance instance)
        {
            TerminateCalled = true;
        }

        #endregion
    }
}
